package jmine.tec.web.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import jmine.tec.proxy.SynchronizedProxyFactory;

/**
 * @author julien
 * @author takeshi
 */
public final class HttpSessionManager {

    /**
     * Private c'tor
     */
    private HttpSessionManager() {
    }

    /**
     * Seta o serviço na sesão do usuário
     * 
     * @param <E> tipo do servico
     * @param session {@link HttpSession}
     * @param service instância do servico
     * @param type tipo
     */
    public static <E> void setService(final HttpSession session, final E service, final Class<E> type) {
        setService(session, service, type, true);
    }

    /**
     * Seta o serviço na sessão do usuário
     * 
     * @param <E> tipo do servico
     * @param session {@link HttpSession}
     * @param service instância do servico
     * @param synched define se o servico sera sincronizado ou nao
     * @param type tipo
     */
    public static <E> void setService(final HttpSession session, final E service, final Class<E> type, final boolean synched) {
        Object delegate;
        if (synched) {
            delegate = SynchronizedProxyFactory.proxyFor(service);
        } else {
            delegate = service;
        }
        session.setAttribute(type.getCanonicalName(), delegate);
    }

    /**
     *Seta o serviço na sessão do usuário
     * 
     * @param <E> tipo do servico
     * @param req {@link HttpSession}
     * @param service instância do servico
     * @param type tipo
     */
    public static <E> void setService(final HttpServletRequest req, final E service, final Class<E> type) {
        setService(req.getSession(), service, type);
    }

    /**
     * Pega o serviço guardado na sessão
     * 
     * @param <E> tipo
     * @param session sessao
     * @param type tipo
     * @return Servico ou null se nao encontrado
     */
    @SuppressWarnings("unchecked")
    public static <E> E getService(final HttpSession session, final Class<E> type) {
        if (type != null && session != null) {
            final Object attribute = session.getAttribute(type.getCanonicalName());
            if (attribute != null && type.isAssignableFrom(attribute.getClass())) {
                return (E) attribute;
            }
        }
        return null;
    }

    /**
     *Pega o serviço guardado na sessão
     * 
     * @param <E> tipo
     * @param req request
     * @param type tipo
     * @return Servico ou null se nao encontrado
     */
    public static <E> E getService(final HttpServletRequest req, final Class<E> type) {
        return getService(req.getSession(), type);
    }

}
